#include "headers/shell.h"
#include "../api/headers/string.h"
#include "../tools/headers/common.h"
#include "../api/headers/io.h"
#include "../fileSystem/headers/fat16.h"
#include "../api/headers/errors.h"
#include "headers/user_progs.h"
#include "../multitasking/headers/task.h"

static exec_type executables[PROGRAM_MAX];
static u32int num_of_installed_execs = 0;
static s8int *exec_names[PROGRAM_MAX];
extern task_t* current_task;
s8int buff[255];
void init_shell()
{
	memset(executables, 0, sizeof(exec_type) * PROGRAM_MAX);
	memset(exec_names, 0, sizeof(s8int*) * PROGRAM_MAX);
	int i;
	install_program(lameWhile,"lame_while\0");
	install_program(tick, "tick\0");
	
	install_program(secondProg, "second\0");
	install_program(memTest, "memTest\0");
	install_program(killHeap, "killHeap\0");
}

void run_shell()
{
	printf("\n");
	while(true)
	{
		printf("Command:->");
		s8int *input = getString((s8int*)buff);

		//s8int input[] = "dsf sdf sdf sd sdfsdf sdf sd";
		s8int *run_command = "run"; //test
  		s8int *rest;
 		s8int *token;
 		s8int *ptr = input;
		token = strtok_r(ptr, " ", &rest);
		ptr = rest;
		u32int ret;
		u32int t = 0;
		if(!strcmp(token, run_command))
		{
			token = strtok_r(ptr, " ", &rest);
			if(!token)
			{
				printf("Usage: run [program name]\nInstalled programs:\n");
				for(t = 0; t < PROGRAM_MAX; t++)
				{
					if(executables[t])
						printf("%s  ", exec_names[t]);
				}
				printf("\n");
					
			}
			else
			{
				ptr = rest;
				int i;
				for(i = 0; i < PROGRAM_MAX; i++)
				{
					if (executables[i]?(!strcmp(token, exec_names[i])):0)
					{
						printf("Forking.\n");
						if(executables[i])
						{
							ret = fork();
							if(getLastError() != NO_ERROR)
							{
								K_PANIC(getLastErrorMessage());
							}
							if(ret == 0)
							{
								exec_type executable = executables[i];
								makeVirtualConsoleFocused(current_task);
								executable();
								printf("Process %d returned\n", current_task->id);
								getString(buff);
								current_task->state = KILLED;
								while(1);
							}
	
						}
						
						printf("\n");
						break;
					}
				}
				if(i >= PROGRAM_MAX)
					printf("No such program.\n");
			}
		}
		else if(!strcmp((s8int*)"help", input))
		{
			FileDescriptor file;
			char filePath[] = "a:/docume~1/help.txt";
			
			printf("Reading help from disk:\n");
			
			getDirectoryFromPath(filePath, &file, true);
			if(getLastError() != NO_ERROR)
			{
				printf("Error getting directory from path: %s\n", getLastErrorMessage());
			}
			
			
			int loaded = loadFile(&file, (u8int*)buff);

			if(getLastError() != NO_ERROR)
				printf("File loading failed: %s\n\n", getLastErrorMessage());
			else
			{
				buff[loaded] = 0;
				printf("%s", buff);
			}
		}
		else
		{
			printf("\nUnknown command\n");
		}
	}
}

BOOL install_program(exec_type executable, s8int *exec_name)
{
	if(num_of_installed_execs != PROGRAM_MAX)
	{
		int i;
		for(i = 0; i < PROGRAM_MAX; i++)
		{
			if(executables[i] == 0)
			{
				printf("%s installed at %d\n", exec_name, i);
				exec_names[i] = exec_name;
				executables[i] = executable;
				num_of_installed_execs++;
				return 1;
			}
		}
	}
	return 0;
}

BOOL remove_program(s8int *exec_name)
{
	int i;
	for(i = 0; i < PROGRAM_MAX; i++)
	{
		if(!strcmp(exec_names[i], exec_name))
		{
			exec_names[i] = 0;
			executables[i] = 0;
			return 1;
		}
	}
	return 0;
}

   		/*while(token = strtok_r(ptr, " ,", &rest)) 
		{
			if(!strcmp(token, run_command))
			{
				//printf("heeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
			}
			
			printf("%s\n", token);
     		ptr = rest;
		}*/
